package com.fxx.face.http.http;

import android.util.Log;


import com.fxx.face.http.common.AuthService;
import com.fxx.face.http.inteface.FaceRequestCallback;
import com.fxx.face.http.utils.LoggerUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;

/**
 * @ProjectName: FaceRecognition
 * @Package: com.baidu.idl.face.platform.ui.http
 * @ClassName: HttpUtils
 * @Description: http请求封装
 * @Author: 付小歆
 * @CreateDate: 2021/12/27 9:36
 */
public class HttpUtils {


    /**
     * 注册人脸
     */
    public static void registerFace(String img_base64, String group_id, String user_id,
                                    String user_info, FaceRequestCallback callback) {
        Map<String, String> map = new HashMap<>();
        map.put("image_type", "BASE64");
        map.put("user_id", user_id);
        map.put("group_id", group_id);
        map.put("user_info", user_info);
        map.put("quality_control", "NORMAL");
        map.put("liveness_control", "NORMAL");
        map.put("image", img_base64);

        getToken(1, map, callback);
    }


    /**
     * 验证人脸
     *
     * @param img_base64
     */
    public static void verifyFace(String img_base64, String user_id, String group_id,
                                  FaceRequestCallback callback) {
        Map<String, String> map = new HashMap<>();
        map.put("image_type", "BASE64");
        map.put("user_id", user_id);
        map.put("group_id_list", group_id);
        map.put("quality_control", "NORMAL");
        map.put("liveness_control", "NORMAL");
        map.put("image", img_base64);

        getToken(2, map, callback);
    }

    /**
     * 删除人脸
     *
     * @param user_id             人脸图片唯一ID
     * @param group_id            人脸库组名
     * @param register_face_token 注册人脸成功时返回的token
     */
    public static void deleteFace(String user_id, String group_id, String register_face_token,
                                  FaceRequestCallback callback) {
        Map<String, String> map = new HashMap<>();
        map.put("user_id", user_id);
        map.put("group_id", group_id);
        map.put("face_token", register_face_token);

        getToken(3, map, callback);
    }

    /**
     * 更新人脸图片
     *
     * @param image_base64
     * @param groupId
     * @param userId
     * @param isUserIdEmptyAddFace userid 为空时 是否注册这个userid人脸用户
     */
    public static void updateFace(String image_base64, String groupId,
                                  String userId, boolean isUserIdEmptyAddFace,
                                  FaceRequestCallback callback) {
        Map<String, String> map = new HashMap<>();
        map.put("image", image_base64);
        map.put("image_type", "BASE64");
        map.put("group_id", groupId);
        map.put("user_id", userId);
        map.put("quality_control", "NORMAL");
        map.put("liveness_control", "NORMAL");
//        UPDATE: 会使用新图替换库中该user_id下所有图片, 若user_id不存在则会报错
//        REPLACE : 当user_id不存在时, 则会注册这个user_id的用户
//        默认使用UPDATE
        map.put("action_type", isUserIdEmptyAddFace ? "REPLACE" : "UPDATE");

        getToken(4, map, callback);
    }

    /**
     * 获取token
     *
     * @param type 1 注册   2 搜索   3 删除  4 更新人脸
     */
    private static void getToken(final int type, final Map<String, String> map,
                                 FaceRequestCallback callback) {
        HttpModel.getToken("client_credentials",
                AuthService.API_KEY,
                AuthService.SECRET_KEY,
                new Observer<ResponseBody>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        callback.onShowDialog();
                    }

                    @Override
                    public void onNext(ResponseBody value) {
                        try {
                            String body = value.string();
                            Log.e("fxx", "====================== getToken ===================");
                            LoggerUtil.json(body);
                            if (body != null && body.length() > 0) {
                                JSONObject obj = new JSONObject(body);
                                if (obj.has("access_token")) {
                                    String token = obj.getString("access_token");
                                    map.put("access_token", token);
                                    switch (type) {
                                        case 1:
                                            Map<String, String> map2 = new HashMap<>();
                                            map2.put("quality_control", "NORMAL");
                                            map2.put("liveness_control", "NORMAL");
                                            map2.put("user_id", map.get("user_id"));
                                            map2.put("group_id_list", map.get("group_id"));
                                            map2.put("image_type", "BASE64");
                                            map2.put("image", map.get("image"));
                                            map2.put("access_token", token);
                                            verifyFace(map, map2, true, callback);
                                            break;
                                        case 2:
                                            verifyFace(map, null, false, callback);
                                            break;
                                        case 3:
                                            deleteFace(map, callback);
                                            break;
                                        case 4:
                                            updateFace(map, callback);
                                            break;
                                    }
                                } else {
                                    //请求失败
                                    String errorMsg = obj.getString("error_description");
                                    callback.onFail(errorMsg);
                                    callback.onDismissDialog();
                                }
                            } else {
                                callback.onFail("接口返回异常，请稍后重试！");
                                callback.onDismissDialog();
                            }
                        } catch (IOException | JSONException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        //由于 接口onError执行后onComplete方法不会执行，所以onDismissDialog在这里调用
                        callback.onFail(e.getMessage());
                        callback.onDismissDialog();
                    }

                    @Override
                    public void onComplete() {
                        //获取token 不做操作

                    }
                });
    }

    /**
     * 验证人脸
     *
     * @param map
     * @param isRegister
     */
    private static void verifyFace(final Map<String, String> map, Map<String, String> map2, final boolean isRegister, FaceRequestCallback callback) {
        HttpModel.verifyFace(isRegister ? map2 : map, new Observer<ResponseBody>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(ResponseBody value) {
                try {
                    String body = value.string();
                    Log.e("fxx", "====================== verifyFace ===================");
                    LoggerUtil.json(body);
                    if (body != null && body.length() > 0) {
                        JSONObject obj = new JSONObject(body);
                        int code = obj.getInt("error_code");
                        switch (code) {
                            case 0:
                                JSONObject resultObj = obj.getJSONObject("result");
                                if (isRegister) {
                                    //注册人脸
                                    if (resultObj != null) {
                                        JSONArray array = resultObj.getJSONArray("user_list");
                                        JSONObject userOjb = array.getJSONObject(0);
                                        if (userOjb != null) {
                                            //人脸库已有数据，无需注册
                                            callback.onFail("人脸已注册");
                                            callback.onDismissDialog();
                                        }
                                    }
                                } else {
                                    //验证人脸
                                    if (resultObj != null) {
                                        JSONArray array = resultObj.getJSONArray("user_list");
                                        JSONObject userOjb = array.getJSONObject(0);
                                        if (userOjb != null) {
                                            double score = userOjb.getDouble("score");
                                            if (score > 80) {
                                                callback.onSuccess("验证成功!");
                                            } else {
                                                callback.onFail("人脸检测不匹配，请重新扫描!");
                                            }
                                        } else {
                                            callback.onFail("未找到匹配的用户!");
                                        }
                                        callback.onDismissDialog();
                                    }
                                }
                                break;
                            case 223122:
                                callback.onFail("质量检测未通过 右眼遮挡程度过高!");
                                callback.onDismissDialog();
                                break;
                            case 223121:
                                callback.onFail("质量检测未通过 左眼遮挡程度过高!");
                                callback.onDismissDialog();
                                break;
                            case 223124:
                                callback.onFail("质量检测未通过 右脸遮挡程度过高!");
                                callback.onDismissDialog();
                                break;
                            case 223114:
                                callback.onFail("请拍摄时不要晃动手机!");
                                callback.onDismissDialog();
                                break;
                            case 223120:
                                callback.onFail("活体检测未通过!");
                                callback.onDismissDialog();
                                break;
                            case 222207:    //未找到匹配用户   相当于用户未注册人脸信息
                                if (isRegister) {
                                    //注册人脸
                                    registerFace(map, callback);
                                } else {
                                    //未找到人脸
                                    callback.onFail("未找到匹配的用户!");
                                    callback.onDismissDialog();
                                }
                                break;
                            default:
                                callback.onFail("检测失败，请重新扫描识别人脸!");
                                callback.onDismissDialog();
                                break;
                        }
                    } else {
                        callback.onFail("接口返回异常，请稍后重试!");
                        callback.onDismissDialog();
                    }
                } catch (IOException | JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onError(Throwable e) {
                //由于 接口onError执行后onComplete方法不会执行，所以onDismissDialog在这里调用
                callback.onFail(e.getMessage());
                callback.onDismissDialog();
            }

            @Override
            public void onComplete() {

            }
        });
    }

    /**
     * 注册人脸
     *
     * @param map
     * @param callback
     */
    private static void registerFace(Map<String, String> map, FaceRequestCallback callback) {
        HttpModel.registerFace(map, new Observer<ResponseBody>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(ResponseBody value) {
                try {
                    String body = value.string();
                    Log.e("fxx", "====================== registerFace ===================");
                    LoggerUtil.json(body);
                    JSONObject obj = new JSONObject(body);
                    int code = obj.getInt("error_code");
                    String msg = obj.getString("error_msg");
                    if (code == 0) {
                        JSONObject result = obj.getJSONObject("result");
                        if (result != null) {
                            String face_token = result.getString("face_token");
                            callback.onRegisterSuccess("人脸采集成功！", face_token);
                        }
                    } else {
                        callback.onFail("采集失败，请重新扫描!");
                    }
                } catch (IOException | JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onError(Throwable e) {
                //由于 接口onError执行后onComplete方法不会执行，所以onDismissDialog在这里调用
                callback.onFail(e.getMessage());
                callback.onDismissDialog();
            }

            @Override
            public void onComplete() {
                callback.onDismissDialog();
            }
        });
    }


    /**
     * 删除人脸
     *
     * @param map
     * @param callback
     */
    private static void deleteFace(Map<String, String> map, FaceRequestCallback callback) {
        HttpModel.deleteFace(map, new Observer<ResponseBody>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(ResponseBody value) {
                try {
                    String body = value.string();
                    Log.e("fxx", "====================== deleteFace ===================");
                    LoggerUtil.json(body);
                    JSONObject obj = new JSONObject(body);
                    int error_code = obj.getInt("error_code");
                    String error_msg = obj.getString("error_msg");
                    if (error_code == 0) {
                        callback.onSuccess("删除人脸成功!");
                    } else {
                        callback.onFail("删除人脸失败!");
                    }
                } catch (IOException | JSONException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onError(Throwable e) {
                //由于 接口onError执行后onComplete方法不会执行，所以onDismissDialog在这里调用
                callback.onFail(e.getMessage());
                callback.onDismissDialog();
            }

            @Override
            public void onComplete() {
                callback.onDismissDialog();
            }
        });
    }

    /**
     * 更新人脸
     *
     * @param map
     * @param callback
     */
    private static void updateFace(Map<String, String> map, FaceRequestCallback callback) {
        HttpModel.updateFace(map, new Observer<ResponseBody>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(ResponseBody value) {
                try {
                    String body = value.string();
                    LoggerUtil.json(body);
                    JSONObject obj = new JSONObject(body);
                    int code = obj.getInt("error_code");
                    String msg = obj.getString("error_msg");
                    switch (code) {
                        case 0:
                            JSONObject result = obj.getJSONObject("result");
                            if (result.has("face_token")) {
                                String face_token = result.getString("face_token");
                                callback.onUpdateSuccess("修改成功!", face_token);
                            }
                            break;
                        case 223103:
                            callback.onFail("找不到该用户人脸信息，修改失败!");
                            break;
                        case 222201:
                        case 222205:
                        case 222206:
                        case 222302:
                            callback.onFail("服务端请求失败!");
                            break;
                        case 222202:
                            callback.onFail("图片中没有人脸!");
                            break;
                        case 222203:
                            callback.onFail("无法解析人脸!");
                            break;
                        case 222204:
                            callback.onFail("从图片的url下载图片失败!");
                            break;
                        case 222207:
                            callback.onFail("未找到匹配的用户!");
                            break;
                        case 222208:
                            callback.onFail("图片的数量错误!");
                            break;
                        case 222209:
                            callback.onFail("face token不存在!");
                            break;
                        case 222210:
                            callback.onFail("人脸库中用户下的人脸数目超过限制!");
                            break;
                        case 222300:
                            callback.onFail("人脸图片添加失败!");
                            break;
                        case 222301:
                        case 222303:
                            callback.onFail("获取人脸图片失败!");
                            break;
                        case 223100:
                            callback.onFail("操作的用户组不存在!");
                            break;
                        case 223104:
                            callback.onFail("group_list包含组数量过多!");
                            break;
                        case 223113:
                            callback.onFail("人脸有被遮挡!");
                            break;
                        case 223114:
                            callback.onFail("请拍摄时不要晃动手机!");
                            break;
                        case 223115:
                            callback.onFail("请到光线适宜的地方拍摄!");
                            break;
                        case 223116:
                            callback.onFail("请勿遮挡面部!");
                            break;
                        case 223117:
                            callback.onFail("app_list包含app数量过多!");
                            break;
                        case 223120:
                            callback.onFail("活体检测未通过!");
                            break;
                        case 223121:
                            callback.onFail("请勿遮挡左眼!");
                            break;
                        case 223122:
                            callback.onFail("请勿遮挡右眼!");
                            break;
                        case 223123:
                            callback.onFail("请勿遮挡左脸颊!");
                            break;
                        case 223124:
                            callback.onFail("请勿遮挡右脸颊!");
                            break;
                        case 223125:
                            callback.onFail("请勿遮挡下巴!");
                            break;
                        case 223126:
                            callback.onFail("请勿遮挡鼻子!");
                            break;
                        case 223127:
                            callback.onFail("请勿遮挡嘴巴!");
                            break;
                        default:
                            callback.onFail("修改失败!");
                            break;
                    }
                } catch (IOException | JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onError(Throwable e) {
                //由于 接口onError执行后onComplete方法不会执行，所以onDismissDialog在这里调用
                callback.onFail(e.getMessage());
                callback.onDismissDialog();
            }

            @Override
            public void onComplete() {
                callback.onDismissDialog();
            }
        });
    }
}
